package com.example.scancodelogindemo.redisqueue.listener;

import com.example.scancodelogindemo.model.QrCodeInfo;
import com.example.scancodelogindemo.model.Result;
import com.example.scancodelogindemo.redisqueue.TopicConstant;
import com.example.scancodelogindemo.service.LongPollFactory;
import com.example.scancodelogindemo.service.QrcodeLoginService;
import com.example.scancodelogindemo.utils.RedisGenerateKeyUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.Objects;

/**
 * @author 傲寒
 * @date 2023/12/7
 */
@Slf4j
@Component
public class QrCodeStateChangeListener implements ApplicationRunner {

    private final RedissonClient redissonClient;

    private final QrcodeLoginService qrcodeLoginService;


    public QrCodeStateChangeListener(RedissonClient redissonClient,
                                     QrcodeLoginService qrcodeLoginService) {
        this.redissonClient = redissonClient;
        this.qrcodeLoginService = qrcodeLoginService;
    }

    @Override
    public void run(ApplicationArguments args) {
        final String topic = RedisGenerateKeyUtils.buildKey(TopicConstant.QRCODE_STATE_CHANGE_TOPIC);
        final RTopic rTopic = redissonClient.getTopic(topic, JsonJacksonCodec.INSTANCE);
        rTopic.addListener(String.class, (channel, qrcodeId) -> {
            log.info("topic: {} 收到消息 {}.", channel, qrcodeId);
            //能够在工厂中获取到长轮询请求链接，表示上次状态监测接口请求在这个服务
            final DeferredResult<Result<QrCodeInfo>> deferredResult = LongPollFactory.get(qrcodeId);
            if (Objects.isNull(deferredResult)) {
                return;
            }
            //在发送状态变更通知，长轮询 立即返回二维码状态
            deferredResult.setResult(Result.ok(qrcodeLoginService.checkQrState(qrcodeId)));
        });
    }

}
